unit GLGUICheckBox;

interface

uses
  Classes,
  VectorGeometry,
  GLGUI2DSprite,
  GLGUIComponent,
  GLGUIWidget,
  GLGUISkin,
  GLGUIWidgetSkin,
  GLGUITokens,
  GLGUIEvent,
  GLGUISkinManager;

type
  TGLGUICheckControl = class(TGLGUIWidget)
  protected
    FIsChecked: Boolean;
    FNormalSkins: TGLGUICustomSkinsList;
    FCheckedSkins: TGLGUICustomSkinsList;
    procedure SetSkin(const ASkin: TGLGUIWidgetSkin); override;
    function GetIsChecked(): Boolean; virtual;
    procedure SetIsChecked(AChecked: Boolean); virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy(); override;
    property IsChecked: Boolean read GetIsChecked write SetIsChecked;
  end;

  TGLGUICheckBox = class(TGLGUILabeled)
  protected
    FBox: TGLGUICheckControl;
    FIsChecked: Boolean;
    procedure SetSkinName(const ASkinName: String); override;
    procedure DoPositionBox();
    function GetIsChecked(): Boolean; virtual;
    procedure SetIsChecked(AChecked: Boolean); virtual;
    procedure OnUpdate(AEvent: TGLGUIEvent);
    procedure OnMouseUp(AEvent: TGLGUIEvent);
    procedure OnFontUpdate(AEvent: TGLGUIEvent);
  public
    constructor Create(AOwner: TComponent); override;
    property IsChecked: Boolean read GetIsChecked write SetIsChecked;
  end;

implementation

constructor TGLGUICheckControl.Create(AOwner: TComponent);
begin
  inherited;
  FNormalSkins := TGLGUICustomSkinsList.Create;
  FCheckedSkins := TGLGUICustomSkinsList.Create;
end;

function TGLGUICheckControl.GetIsChecked(): Boolean;
begin
  Result := FIsChecked;
end;

procedure TGLGUICheckControl.SetIsChecked(AChecked: Boolean);
var
  i: Integer;
begin
  if AChecked <> FIsChecked then
  begin
    FIsChecked := AChecked;
    if(FIsChecked)then
    begin
      for i := 0 to FSkinSubWidgets.Count - 1 do
        if (TGLGUI2DSpriteCustom(FSkinSubWidgets[i]) is TGLGUI2DSprite) then
          TGLGUI2DSprite(FSkinSubWidgets[i]).Skin := FCheckedSkins[i];
    end
    else
      for i := 0 to FSkinSubWidgets.Count - 1 do
        if (TGLGUI2DSpriteCustom(FSkinSubWidgets[i]) is TGLGUI2DSprite) then
          TGLGUI2DSprite(FSkinSubWidgets[i]).Skin := FNormalSkins[i];
  end;
end;

procedure TGLGUICheckControl.SetSkin(const ASkin: TGLGUIWidgetSkin);
var
  i: Integer;
  vSkin: TGLGUICustomSkin;
begin
  inherited;
  for i := 0 to ASkin.SubWidgetsCount - 1 do
  begin
    vSkin := GUISkinManager.GetSkinByName(ASkin.SubWidgets[i].SkinName);
    FNormalSkins.Add(vSkin);
    vSkin := GUISkinManager.GetSkinByName(ASkin.SubWidgets[i].SkinName + '_Checked');
    FCheckedSkins.Add(vSkin);
  end;
end;

destructor TGLGUICheckControl.Destroy();
begin
  FNormalSkins.Free;
  FCheckedSkins.Free;
  inherited;
end;

constructor TGLGUICheckBox.Create(AOwner: TComponent);
begin
  inherited;
  FBox := TGLGUICheckControl.CreateAsChild(Self);
  FLabel.AutoBound := False;
  FLabel.Text := 'TGLGUICheckBox';
  Height := FLabel.Height;
  FLabel.AutoBound := True;
  FLabel.MoveLast;
  FBox.Height := 16;
  FBox.Width := 16;
  FBox.Align := galLeft;
  FBox.EventBehaviour := ebPassEvent;
  AddSubWidget(FBox);
  CursorImage := -21;
  DoPositionBox();
  AddEventListener(GUIChangeEvent, OnUpdate);
  AddEventListener(MouseUpEvent, OnMouseUp);
  FLabel.AddEventListener(FontUpdateEvent, OnFontUpdate);
end;

procedure TGLGUICheckBox.SetSkinName(const ASkinName: String);
begin
  FSkinName := ASkinName;
  FBox.SkinName := FSkinName;
end;

procedure TGLGUICheckBox.DoPositionBox();
begin
  FLabel.Width := Width - FBox.Width - 10;
  FLabel.Position.X := (FBox.Width - FLabel.Width + FLabel.TextWidth)/2;
end;

function TGLGUICheckBox.GetIsChecked(): Boolean;
begin
  Result := FIsChecked;
end;

procedure TGLGUICheckBox.SetIsChecked(AChecked: Boolean);
begin
  if AChecked <> FIsChecked then
  begin
    FIsChecked := AChecked;
    FBox.IsChecked := FIsChecked;
  end;
end;

procedure TGLGUICheckBox.OnUpdate(AEvent: TGLGUIEvent);
begin
  DoPositionBox();
end;

procedure TGLGUICheckBox.OnMouseUp(AEvent: TGLGUIEvent);
begin
  FIsChecked := not FIsChecked;
  FBox.IsChecked := FIsChecked;
  if(FBox.State = GLGUIFocused) then
  begin
    FBox.State := GLGUIEnabled;
    FBox.State := GLGUIFocused;
  end;
end;

procedure TGLGUICheckBox.OnFontUpdate(AEvent: TGLGUIEvent);
begin
  Height := MaxFloat(FBox.Height, Flabel.Height);
  DoPositionBox();
end;

end.

